﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Web.Mvc;
using CSF.Service.Accounts.Client;
using System.Security.Principal;
using CSF.Security.Data;
using CSF.MultiLang.Data;

namespace CSF.Utility.Mvc
{
    public class SecureController : Controller
    {
        protected Application _application = null;
        protected UserSession _userSession = null;

        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            HandleUserSession(filterContext);

            HandleApplication(filterContext);

            FillViewBag(filterContext);

            base.OnAuthorization(filterContext);
        }

        [NonAction]
        private void HandleApplication(AuthorizationContext filterContext)
        {
            if (filterContext.RouteData.Values.ContainsKey("appCode"))
            {
                string appCode = (string)filterContext.RouteData.Values["appCode"];
                _application = (Application)filterContext.HttpContext.Cache[appCode + "Application"];
                if (_application == null)
                {
                    ApplicationSvcClient svc = new ApplicationSvcClient();
                    _application = svc.GetOneByCode(appCode);

                    if (_application != null)
                    {
                        filterContext.HttpContext.Cache.Add(appCode + "Application", _application, null,
                                System.Web.Caching.Cache.NoAbsoluteExpiration,
                                new TimeSpan(0, 20, 0),
                                System.Web.Caching.CacheItemPriority.Normal,
                                null);
                    }
                }
                if (_application != null)
                {
                    ViewBag.AppId = _application.Id;
                }
            }
        }

        [NonAction]
        protected virtual void FillViewBag(AuthorizationContext filterContext)
        {
            IEnumerable<LangDef> langDefs = (IEnumerable<LangDef>)filterContext.HttpContext.Cache["LangDefs"];
            if (langDefs == null)
            {
                LangDefSvcClient langDefSvc = new LangDefSvcClient();
                langDefs = langDefSvc.GetAll();

                filterContext.HttpContext.Cache.Add("LangDefs", langDefs, null,
                            System.Web.Caching.Cache.NoAbsoluteExpiration,
                            new TimeSpan(0, 20, 0),
                            System.Web.Caching.CacheItemPriority.Normal,
                            null);
            }
            ViewBag.LangDefs = langDefs;
        }

        /// <summary>
        /// 获取用户会话，并生成用户登录状态
        /// </summary>
        /// <param name="filterContext"></param>
        [NonAction]
        private void HandleUserSession(AuthorizationContext filterContext)
        {
            var request = filterContext.HttpContext.Request;
            if (!string.IsNullOrEmpty(request["SessionId"])
                && !filterContext.HttpContext.Request.IsAuthenticated)
            {
                var sessionId = request["SessionId"];
                _userSession = (UserSession)(filterContext.HttpContext.Cache[sessionId]);
                if (_userSession == null)
                {
                    AuthenticateSvcClient svc = new AuthenticateSvcClient();
                    _userSession = svc.VerifySession(sessionId);

                    if (_userSession != null)
                    {
                        filterContext.HttpContext.Cache.Add(sessionId, _userSession, null,
                            System.Web.Caching.Cache.NoAbsoluteExpiration,
                            new TimeSpan(0, 20, 0),
                            System.Web.Caching.CacheItemPriority.Normal,
                            null);
                    }
                }
                if (_userSession != null)
                {
                    GenericIdentity identity = new GenericIdentity(_userSession.UserName);
                    GenericPrincipal principal = new GenericPrincipal(identity, null);
                    filterContext.HttpContext.User = principal;
                }
            }
        }
    }
}
